Skip to content

ci(dummies): validate packaged netstandard2.0 and net8.0 assets#195

Merged
Reefact merged 2 commits into
mainfrom
claude/issue-191-adrry5
Jul 19, 2026
Merged

ci(dummies): validate packaged netstandard2.0 and net8.0 assets#195
Reefact merged 2 commits into
mainfrom
claude/issue-191-adrry5

Conversation

@Reefact

@Reefact Reefact commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Summary

Dummies ships lib/netstandard2.0 and lib/net8.0 in one package, but Dummies.UnitTests targets net10.0 and only ever exercises the net8.0 asset NuGet resolves as nearest-compatible. This adds a dedicated workflow that packs the real .nupkg and consumes it once per consumer TFM, so the netstandard2.0 asset that actually ships is executed and validated.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring
  • Analyzer / diagnostic change
  • Tests
  • Documentation
  • Build / CI / tooling

Changes

  • Add .github/workflows/dummies.yml: packs Dummies under the release SDK (.NET 10), then consumes the packed package from an isolated project once per consumer TFM — net8.0net8.0 asset, net6.0netstandard2.0 asset — on the real .NET 6 / .NET 8 runtimes.
  • Add tools/dummies-check/ (deliberately outside FirstClassErrors.sln), mirroring the pack-and-consume pattern of tools/floor-check/: throwaway per-run version, nuget.config with <clear/> + packageSourceMapping pinning Dummies to the local feed, project-local RestorePackagesPath. No nested global.json: the contract under test is the TFM asset, not the SDK.
  • Program.cs proves by reflection which asset loaded, asserts the conditional net8.0 surface (DateOnly/TimeOnly/Int128/UInt128/Half) is present only on the intended asset, exercises the common smoke surface (scalars, constraints, composition, collections, seeded reproducibility), and exits non-zero naming the regressed asset (via an ASSET=/RESULT= banner the workflow greps).
  • .gitignore: ignore the check's generated local-feed/, packages/, *.log.
  • A net472 leg (netstandard2.0 on the .NET Framework CLR) is left as a documented follow-up — it would be the repository's first Framework target (Windows runner + Framework toolchain).

Testing

Ran locally. This environment carries only the .NET 10 runtime, so both consumer legs were run with DOTNET_ROLL_FORWARD=LatestMajor onto .NET 10; CI exercises the real .NET 6 / .NET 8 runtimes. Local runs therefore prove asset selection, reflection present/absence, the smoke surface and the red path — not runtime behaviour on 6/8, which CI adds.

  • dotnet pack Dummies/Dummies.csproj.nupkg contains both lib/netstandard2.0 and lib/net8.0.
  • net8.0 consumer → loaded .NETCoreApp,Version=v8.0, modern generators present, RESULT=PASS.
  • net6.0 consumer → loaded .NETStandard,Version=v2.0, modern generators absent, RESULT=PASS.
  • Negative check: injecting a missing entry point produced RESULT=FAIL and a non-zero exit tagged with the asset — the red path works.

The full solution build/test was not run: this change is additive and lives entirely outside FirstClassErrors.sln.

  • dotnet build FirstClassErrors.sln
  • dotnet test FirstClassErrors.sln
  • Analyzer tests pass (FirstClassErrors.Analyzers.UnitTests)

Documentation

  • No documentation change required

Architecture decisions

  • No architectural decision in this pull request

Related issues

Closes #191


🤖 Generated with Claude Code
https://claude.ai/code/session_012NhzokwQfe9ZiL4Bc1dt7Y


Generated by Claude Code

claude and others added 2 commits July 19, 2026 15:39
Dummies ships lib/netstandard2.0 and lib/net8.0 in one package, but
Dummies.UnitTests targets net10.0 and so only ever exercises the net8.0
asset NuGet resolves as nearest-compatible. The netstandard2.0 asset is
compiled but never executed by a test, so a downlevel-only regression
(conditional compilation, API availability, seeded reproducibility)
could reach NuGet with the suite green.

Add a dedicated workflow that packs the real .nupkg and consumes it from
an isolated project (tools/dummies-check) once per consumer TFM,
mirroring the pack-and-consume pattern of tools/floor-check:

* net8.0 consumer forces the net8.0 asset (modern generators present);
* net6.0 consumer forces the netstandard2.0 asset (modern generators
  absent), the leg the net10.0 test project can never reach.

The consumer proves by reflection which asset loaded, checks the
conditional net8.0 surface (DateOnly/TimeOnly/Int128/UInt128/Half) is
present only on the intended asset, exercises the common smoke surface
(scalars, constraints, composition, collections, seeded reproducibility),
and exits non-zero naming the asset that regressed.

A net472 leg (netstandard2.0 on the .NET Framework CLR) is left as a
documented follow-up: it would be the repository's first Framework target.

Refs: #191
@Reefact
Reefact merged commit 3762e4f into main Jul 19, 2026
14 checks passed
@Reefact
Reefact deleted the claude/issue-191-adrry5 branch July 19, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dummies: Exercise both packaged target-framework assets in compatibility tests

2 participants